<?php

namespace app\user\service;

use app\common\formula\Calculate;
use app\model\RatingScaleFactorLevelModel;
use app\model\RatingScaleFactorModel;
use app\model\RatingScaleFactorWarningModel;
use app\model\RatingScaleModel;
use app\model\RatingScaleQuestionAnswerModel;
use app\model\school\SchoolCourseChapterResultFactorScoreModel;
use app\model\school\SchoolCourseChapterResultModel;
use think\facade\Queue;
use think\Service;

class SchoolService extends Service
{
    public string $message = '';
    public int $line;
    public array $resultData = [];
    public int $ResultId;
    public int $is_valid = 1;//是否有效【0否，1是】

    /**
     * 生成报告
     * @param array $data 用户提交的数据
     * @param int $channel 答题渠道【1.任务测评，2.自我测评】
     * @return bool
     */
    public function generateReport(array $data, int $channel): bool
    {
        try {
            $RatingScaleModel = new RatingScaleModel();
            $RatingScaleInfo = $RatingScaleModel->find($data['rating_scale_id']);
            //答题总分和因子总分
            $RatingScaleQuestionAnswerModel = new RatingScaleQuestionAnswerModel();
            $answerList = $RatingScaleQuestionAnswerModel->where('rating_scale_id', '=', $data['rating_scale_id'])->select()->toArray();
            $scoreData = [];
            foreach ($answerList as $item) {
                $scoreData[$item['id']] = $item;
            }
            $question_num = array_column($answerList, 'question_id');
            $question_num = count(array_unique($question_num));
            $scoreResults = [];
            $isWarning = 0;//是否预警
            $totalScore = 0;//总分
            if ($question_num > count($data['userAnswer'])) {
                $this->is_valid = 0;
            }
            foreach ($data['userAnswer'] as $AnswerId) {
                $questionNum = $scoreData[$AnswerId]['num'] ?? 0;
                if (!$questionNum) {
                    continue;
//                    throw new \Exception('答案参数错误！');
                }
                $totalScore += $scoreData[$AnswerId]['score'] ?? 0;
                $scoreResults[$questionNum] = [
                    'user_answer_id' => $AnswerId,
                    'question_id' => $scoreData[$AnswerId]['question_id'] ?? 0,
                    'score' => $scoreData[$AnswerId]['score'] ?? 0,
                    'num' => $questionNum
                ];
            }
            $Calculate = new Calculate();
            $CalculateResults = $Calculate->getUserFactorScore($scoreResults, $data['rating_scale_id'], $RatingScaleInfo['mode_id'],$data['uid'],$this->is_valid);
            $factorResults = $CalculateResults['factorResults']??[];
            $this->is_valid = $CalculateResults['is_valid']??0;

            $warningImportantArr = [];

            $RatingScaleFactorLevelModel = new RatingScaleFactorLevelModel();
            $levelList = $RatingScaleFactorLevelModel->field('id,factor_id,level,low_range,high_range')
                ->where([
                    'rating_scale_id' => $data['rating_scale_id'],
                    'mode_id' => $RatingScaleInfo['mode_id']
                ])->with(['isTotal'])->select()->toArray();
            foreach ($levelList as $item) {
                $score = $factorResults[$item['factor_id']]['score'] ?? 0;
                if ($score >= $item['low_range'] && $score <= $item['high_range']) {
                    $factorResults[$item['factor_id']]['factor_level_id'] = $item['id'];
                    $factorResults[$item['factor_id']]['level'] = $item['level'];
                    $factorResults[$item['factor_id']]['is_total'] = $item['is_total'];
                    $factorResults[$item['factor_id']]['score'] = $score;
                    $factorResults[$item['factor_id']]['is_warning'] = 0;
                    $factorResults[$item['factor_id']]['warning_id'] = 0;
                    $factorResults[$item['factor_id']]['important_level'] = 0;
                }
                if ($item['is_total'] == 1 && $item['level'] == 7){
                    $warningLevelId = $item['id'];
                }
            }

            $RatingScaleFactorWarningModel = new RatingScaleFactorWarningModel();
            $warningList = $RatingScaleFactorWarningModel->field('id,type,factor_id,condition1_level')
                ->where([
                    'rating_scale_id' => $data['rating_scale_id'],
                    'mode_id' => $RatingScaleInfo['mode_id']
                ])->with(['factorName'])->select()->toArray();

            switch ($RatingScaleInfo['previous_name']) {
                case "明尼苏达多相人格测验399（MMPI)":
                    break;
                case "中小学生心理健康诊断测验(MHT)":
                    foreach ($warningList as $value) {
                        //TODO::2类型暂时没数据不写
                        //预警条件类型。1：单项，2：多项，3：总分关连预警
                        switch ($value['type']) {
                            case 1:
                            case 2:
                                if (isset($factorResults[$value['factor_id']]['level']) && $factorResults[$value['factor_id']]['level'] == $value['condition1_level']) {
                                    $factorResults[$value['factor_id']]['is_warning'] = 1;
                                    $factorResults[$value['factor_id']]['warning_id'] = $value['id'];
                                    $factorResults[$value['factor_id']]['important_level'] = $value['condition1_level'];
                                    if ($value['factor_name'] == '总分') {
                                        $isWarning = 1;
                                    }
                                }
                                break;
                        }
                    }
                    break;
                default:
                    foreach ($warningList as $value) {
                        //TODO::2类型暂时没数据不写
                        //预警条件类型。1：单项，2：多项，3：总分关连预警
                        switch ($value['type']) {
                            case 1:
                            case 2:
                                if (isset($factorResults[$value['factor_id']]['level']) && $factorResults[$value['factor_id']]['level'] == $value['condition1_level']) {
                                    $isWarning = 1;
                                    $factorResults[$value['factor_id']]['is_warning'] = 1;
                                    $factorResults[$value['factor_id']]['warning_id'] = $value['id'];
                                    $factorResults[$value['factor_id']]['important_level'] = $value['condition1_level'];
                                }
                                break;
                            case 3:
                                //涉及到顺序问题，总分关连预警放到循环外面处理
                                $totalWarningId = $value['id'];
                                break;
                        }
                    }
            }
            if ($isWarning) {
                foreach ($factorResults as &$v) {
                    if (!empty($warningImportantArr)){
                        if ($v['important_level'] > $warningImportantArr['important_level']) {
                            $warningImportantArr = [
                                'factor_id' => $v['factor_id'],
                                'important_level' => $v['important_level'],
                                'id' => $v['warning_id']
                            ];
                        }
                    }else{
                        $warningImportantArr = [
                            'factor_id' => $v['factor_id'],
                            'important_level' => $v['important_level'],
                            'id' => $v['warning_id']
                        ];
                    }
                    if ($v['is_warning'] == 0 && $v['is_total'] == 1 && !empty($totalWarningId) && !empty($warningLevelId)) {
                        $v['is_warning'] = 1;
                        $v['warning_id'] = $totalWarningId;
                        $v['factor_level_id'] = $warningLevelId;
                    }
                }
            }
            $addFactorScores = [];
            foreach ($factorResults as $value) {
                $addFactorScores[] = [
                    'factor_id' => $value['factor_id'] ?? 0,
                    'factor_level_id' => $value['factor_level_id'] ?? 0,
                    'score' => $value['score'] ?? 0,
                    'is_warning' => $value['is_warning'] ?? 0,
                    'warning_id' => $value['warning_id'] ?? 0,
                    'time' => time()
                ];
            }
            switch ($channel) {
                case 9:
                    $type = 'school';
                    //任务测评
                    $ResultData = [
                        'unit_id' => $data['unit_id'],
                        'chapter_id' => $data['chapter_id'],
                        'uid' => $data['uid'],
                        'rating_scale_id' => $data['rating_scale_id'],
                        'question_answer' => json_encode($data['userAnswer'], true),
                        'total_score' => $totalScore,
                        'finish_used_time' => $data['finish_used_time'],
                        'is_valid' => $this->is_valid,
                        'time' => time()
                    ];
                    //是否预警
                    if ($isWarning == 1) {
                        $ResultData['is_warning'] = 1;
                        $ResultData['warning_id'] = $warningImportantArr['id'] ?? 0;
                        $ResultData['warning_factor_id'] = $warningImportantArr['factor_id'] ?? 0;
                    }
                    if (!$this->addTaskUserResult($ResultData, $addFactorScores)) throw new \Exception($this->message);
                    break;
                default:
                    // 如果没有匹配的值
                    throw new \Exception('测评类型错误！');
            }
            $RatingScaleInfo->inc('heat')->save();
            if (!Queue::push(\app\job\CronJob::class, [
                'method' => 'personCharts',
                'data' => [
                    'type' => $type,
                    'id' => $this->ResultId
                ],
            ], 'CronJob')) throw new \Exception('生成报告-队列添加失败！');
            if (!Queue::push(\app\job\CronJob::class, [
                'method' => 'evaluationLog',
                'data' => [
                    'data' => [
                        'company_id' => $data['company_id'],
                        'areas_id' => $data['areas_id'],
                        'unit_id' => $data['unit_id'],
                        'uid' => $data['uid'],
                        'finish_used_time' => $data['finish_used_time'],
                        'rating_scale_id' => $data['rating_scale_id'],
                    ],
                    'channel' => $channel
                ],
            ], 'CronJob')) throw new \Exception('测评记录-队列添加失败！');
            return true;
        } catch (\Exception $e) {
            $this->message = $e->getMessage();
            $this->line = $e->getLine();
            return false;
        }

    }


    /**
     * 新增任务用户答题结果
     * @param $ResultData
     * @param $addFactorScores
     * @return bool
     */
    public function addTaskUserResult($ResultData, $addFactorScores): bool
    {
        try {
            $SchoolCourseChapterResultModel = new SchoolCourseChapterResultModel();
            //添加结果记录
            $resultId = $SchoolCourseChapterResultModel->insertGetId($ResultData);
            $this->ResultId = $resultId;
            //因子得分
            foreach ($addFactorScores as &$item) {
                $item['result_id'] = $resultId;
            }
            //添加因子得分记录
            $SchoolCourseChapterResultFactorScoreModel = new SchoolCourseChapterResultFactorScoreModel();
            $SchoolCourseChapterResultFactorScoreModel->insertAll($addFactorScores);
            return true;
        } catch (\Exception $e) {
            $this->message = $e->getMessage();
            $this->line = $e->getLine();
            return false;
        }

    }

}